package il.ac.tau.dbcourse.gui;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;



public class ProgressBarWindow {
  Boolean DEBUG =true;
  Shell shell;
//  Shell parentShell;
 // Button button;
  Label label;
  ProgressBar progressBar;
 // final Thread thread;
  boolean timeToQuit;
  boolean ShowPrecentage;
  PrintStream printStream;
  OutputStream outputStream;
  public Boolean sonEquals(Object obj)
  {
	  return progressBar.equals(obj);
  }
  public void setSelection(int value)
  {
	  progressBar.setSelection(value%progressBar.getMaximum());
  }
  public void setMinimum(int value)
  {
	  progressBar.setMinimum(value);
  }
  public void setMaximum(int value)
  {
	  progressBar.setMaximum(value);
  }
  public int getSelection()
  {
	 return progressBar.getSelection();
  }
  public int getMaximum()
  {
	  return progressBar.getMaximum();
  }
  public int getMinimum()
  {
	  return progressBar.getMinimum();
  }
  public void setTimeToQuit(Boolean b)
  {
	  timeToQuit=b;
  }
  public Boolean getTimeToQuit(){
	  return timeToQuit;
  }
  public Shell getShell(){
	  return shell;
  }
  public PrintStream getPrintStream(){
	  return printStream;
  }
  
  public ProgressBarWindow(Shell shell2) {
	ShowPrecentage=false;
	timeToQuit=false;
    shell= shell2;
    outputStream = new OutputStream() {
    	final private StringBuilder stringb = new StringBuilder();
        @Override
        public void write(int b) throws IOException {
            //stringb.
        	this.stringb.append((char) b );
        }
        private void clearBuffer(){
        	stringb.delete(0, stringb.length());
        }
        public String toString(){
        	String endofline = System.getProperty("line.separator");
        	String b =this.stringb.toString();
        	if (DEBUG&!b.equals("")) System.out.println("b is: "+b);
        	if (b.contains("%%%%%")){
        		System.out.println("clearing buffer");
        	    this.clearBuffer();
        	    
        	}
        	if (b.contains("%%%%%")){
        		b=b.substring(b.lastIndexOf("%%%%%")+5);
        	}
        	if (b.startsWith(endofline)){
        		b=b.substring(endofline.length());
        	}
        	
        		
        		//System.out.println("tostring returned empty");
    	    
        	return b;
            
        }
//		@Override
//		public void write(int b) throws IOException {
//			 final int a = b; 
//			 
//			 shell.getDisplay().asyncExec(new Runnable(){
//	    				 public void run() {
//	    					 label.setText("J & "+ a);
//	    					 System.out.println("label is set to:"+label.getText());
//	    					// shell.redraw();
//	    			   }
//				 });
//				
//			
//		}
	};
    printStream = new PrintStream(outputStream, true);
    GridLayout gridLayout = new GridLayout(1, true);
    shell.setLayout(gridLayout);
    
    shell.addListener (SWT.Close, new Listener () {
		public void handleEvent (Event event) {
			event.doit = timeToQuit;
		}
	});
    shell.addDisposeListener(new DisposeListener() {
		
		@Override
		public void widgetDisposed(DisposeEvent arg0) {
			if (DEBUG)
				
				System.out.println("setting timeToQuit To on cause widget disposed");
			timeToQuit=true;
			if (DEBUG)
				System.out.println("disposing shell");
		}
	});
   
    progressBar = new ProgressBar(shell, SWT.SMOOTH);
   
    label = new Label(shell,SWT.HORIZONTAL);
    label.setText("");
    label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    
    
    progressBar.addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {
        String string = (int)(progressBar.getSelection() * 1.0 /
      (progressBar.getMaximum()-progressBar.getMinimum()) * 100) + "%";
        Point point = progressBar.getSize();
       
        
        FontMetrics fontMetrics = e.gc.getFontMetrics();
        int width = fontMetrics.getAverageCharWidth() * string.length();
        int height = fontMetrics.getHeight();
        e.gc.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
        if (ShowPrecentage) e.gc.drawString(string, (point.x-width)/2 , (point.y-height)/2, true);
        String tmpS=outputStream.toString();
        if (!tmpS.equals(""))
        {
        	label.setText(tmpS);
        //System.out.println("setting Label to: "+ outputStream.toString());
        	System.out.println("label text set to: "+ label.getText());
        	label.redraw();
        	Point size =new Point(300, shell.getSize().y);
        	shell.pack();
        	shell.setSize(shell.getSize().x,shell.getSize().y);
        	shell.setMinimumSize(shell.getSize());
            shell.redraw();
        	
        	
        }
      }
    });
    progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    shell.setSize(300, 90);
    shell.open();
  }
   
  static public ProgressBarWindow initProgressBar(Composite comp, String withText) {
		final Shell progressBarShell;
		progressBarShell = new Shell(comp.getShell());
		progressBarShell.setText(withText);
		final ProgressBarWindow progressBar;

		progressBar = new ProgressBarWindow(progressBarShell);
		progressBar.setMinimum(0);
		progressBar.setMaximum(1000);

		return progressBar;

	}

	public static void startProgressOn(final ProgressBarWindow progressBar,
			final Thread main) {
		final Thread thread = new Thread() {
			public void run() {
				for (int i = 0; main.isAlive() & !progressBar.getTimeToQuit(); i++) {
					final int value;
					// if (i==progressBar.getMaximum()) i=0;
					value = i;
					try {
						Thread.sleep(10);
						progressBar.getShell().getDisplay().asyncExec(
								new Runnable() {
									public void run() {
										if (!progressBar.equals(null)
												&& !progressBar.getTimeToQuit()
												&& !progressBar.sonEquals(null))
											progressBar.setSelection(value);
									}
								});
					} catch (Exception e) {
					}

				}
				progressBar.setTimeToQuit(true);
				// progressBarShell.close();

			}
		};

		progressBar.setTimeToQuit(false);
		main.start();
		thread.start();
		// thread.

		while (!progressBar.getShell().isDisposed() && thread.isAlive()) {
			if (!progressBar.getShell().getDisplay().readAndDispatch())
				progressBar.getShell().getDisplay().sleep();
		}
		if (!progressBar.getShell().isDisposed())
			progressBar.getShell().close();
	}
  
}